#ifndef YCBASEDOWNLOADER_H
#define YCBASEDOWNLOADER_H
#include "base/task/task.h"
#include <QDir>
#include <QNetworkReply>
#include <QPointer>

namespace yc {

class Service;

struct DownloadResource
{
    QString url; // 路径
    QString local_name; // 本地文件名
    qint64 bytes_total; // 字节数

    DownloadResource() : bytes_total(0) { }
    DownloadResource(const QString& u, const QString& l, qint64 bt = 0)
        : url(u), local_name(l), bytes_total(bt)
    {
    }
};

class Downloader : public Task
{
    Q_OBJECT

public:
    Downloader(Service* service, const QString& service_url, const QDir& local_dir,
               bool auto_delete = true, int timeout = 0, QObject* parent = nullptr);
    Downloader(Service* service, const QString& service_url,
               const QList<DownloadResource>& resources, const QDir& local_dir,
               QObject* parent = nullptr);
    Downloader(Service* service, const QString& service_url,
               const QList<DownloadResource>& resources, const QDir& local_dir, int id,
               bool auto_delete, int timeout, int try_times, QObject* parent = nullptr);
    ~Downloader();

    void setServiceUrl(const QString& url) { service_url_ = url; }
    void setLocalDir(const QDir& dir) { local_dir_ = dir; }
    const QList<DownloadResource>& resources() const;
    void setHeaders(const QMap<QString, QString>& headers);
    void ignoreFailure(bool setting);
    void addResource(const DownloadResource& resource);

    QString statusMessage() const override;
    qint64 evaluateTotalMSecs() const override;

Q_SIGNALS:
    void progress(qint64 bytes_received, qint64 bytes_total);
    void downloaded(const QString& filename);

private:
    void startImpl() override;
    void terminateImpl() override;
    void onTimeout() override;
    void closeFile(bool remove_file = false);
    void startNextRequest();
    void startSingleTimer(int interval, int deviation = 5000);
    void stopSingleTimer();

    QPointer<Service> service_;
    bool ignore_failure_;
    QString service_url_;
    QList<DownloadResource> resources_;
    QDir local_dir_;
    QPointer<QNetworkReply> reply_;
    QFile* file_;
    qint64 bytes_received_;
    qint64 bytes_total_;
    qint64 current_bytes_total_;
    bool has_bytes_total_;
    bool added_total_;
    bool has_timeout_option_;
    QMap<QString, QString> headers_;
    int try_times_;
    int current_try_times_;
    DownloadResource current_;
    QTimer* single_timer_;
    bool single_timer_started_;
};

} // namespace yc

#endif // YCBASEDOWNLOADER_H
